Skip to content

Support Integer module parameters on synthesized modules#1034

Open
nanavati wants to merge 1 commit into
B-Lang-org:mainfrom
nanavati:integer-parameters
Open

Support Integer module parameters on synthesized modules#1034
nanavati wants to merge 1 commit into
B-Lang-org:mainfrom
nanavati:integer-parameters

Conversation

@nanavati

Copy link
Copy Markdown
Collaborator

Summary

Module arguments of type Integer marked with the parameter pragma/keyword now become true Verilog parameters on synthesis boundaries, matching the existing support for String and Real parameters. Previously this was rejected with T0043 ("not in the Bits class").

  • GenWrap: accept Integer as a parameter-only type, so the wrapper passes the argument through symbolically instead of adding an unsatisfiable Bits proviso.
  • IExpand: PrimIntegerToBit/PrimIntegerToUIntBits/PrimIntegerToIntBits reduce a symbolic ICModParam Integer to the same reference re-typed at the target width; it lowers to an ASParam and renders as a reference to the Verilog parameter. Since parameter values are canonicalized to Bit#(32) at instantiation sites (PrimParam in the Prelude), this single change enables fromInteger of the parameter in the module body, $display of the parameter, and forwarding the parameter to a submodule's parameter:
    module mkSub(...);
      parameter step = 0;
      ...
      assign count$D_IN = count + step ;
    ...
    mkSub #(.step(32'd5)) the_sub(...);   // literal value
    mkSub #(.step(step)) inner(...);      // forwarded from an enclosing parameter
  • IExpandUtils: isParamOnlyType includes Integer, so an Integer module argument without the parameter pragma now gets the intended EParamOnlyType (G0120) user error instead of an internal error (getIOProps.size: ATAbstract).
  • SimExpand: Bluesim gives a parameter input of abstract type Integer its canonical Bit#(32) representation when building the SimPackage, so the generated C++ takes an ordinary 32-bit constructor argument instead of hitting an internal error (aTypeToCType: Unexpected abstract type) at link time.

Values remain bounded to 32 bits, checked during elaboration (T0051 for out-of-range literals), matching the longstanding import-BVI treatment of Integer parameters; wider constants can use Bit#(n) parameters as before.

Test plan

  • New testsuite directory bsc.verilog/parameters/integer (mirrors the string/real siblings), run on both backends: displays the parameter, uses it in hardware via fromInteger (UInt counter compare), instantiates from a parent with a concrete value, checks the generated Verilog renders parameter val = 0; and .val(32'd5), and verifies the missing-pragma case reports G0120.
  • Full testsuite (fullparallel, iverilog + SystemC + Bluesim) run with the change: PASS=18894 XFAIL=129 XPASS=0 ERROR=0, with zero regressions relative to a baseline run at the same parent commit (the only failing directory, bsc.long_tests/log2_loop/actionvalue, reproduces identically without this change).
  • Manually verified Bluesim output is byte-identical to iverilog for a parameterized counter (two instances stepping by 1 and 5), parameter forwarding values (chained=0,7,14,21 in both backends), $display of the parameter, negative values (32'hFFFFFFFD), and identical T0051 rejection of a 2^40 value under both -verilog and -sim.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GSzANC9YNPwjtQf2Tsbj7L

Module arguments of type Integer marked with the `parameter`
pragma/keyword now become true Verilog parameters on synthesis
boundaries, matching the existing support for String and Real:

- GenWrap: accept Integer as a parameter-only type, so the wrapper
  passes the argument through symbolically instead of requiring an
  unsatisfiable Bits instance (previously error T0043).

- IExpand: PrimIntegerToBit / PrimIntegerToUIntBits /
  PrimIntegerToIntBits reduce a symbolic ICModParam of type Integer
  to the same reference re-typed at the target width, which lowers
  to an ASParam and renders as a reference to the Verilog parameter.
  Because parameter values are canonicalized to Bit#(32) at
  instantiation sites (PrimParam in the Prelude), this one change
  enables fromInteger of the parameter in the module body, $display
  of the parameter, and forwarding the parameter to a submodule's
  parameter (previously error G0013).

- IExpandUtils: isParamOnlyType includes Integer, so an Integer
  module argument without the parameter pragma gets the intended
  EParamOnlyType user error instead of an internal error
  (getIOProps.size: ATAbstract).

- SimExpand: Bluesim gives a parameter input of abstract type
  Integer its canonical Bit#(32) representation when building the
  SimPackage, so the generated C++ takes an ordinary 32-bit
  constructor argument instead of hitting an internal error
  (aTypeToCType: Unexpected abstract type) at link time.

Values remain bounded to 32 bits, checked during elaboration
(T0051), matching the longstanding import-BVI treatment of Integer
parameters; wider constants can use Bit#(n) parameters as before.

Adds testsuite coverage in bsc.verilog/parameters/integer, run on
both backends, including the negative test for a missing parameter
pragma.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GSzANC9YNPwjtQf2Tsbj7L
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants